package mq

import (
	"time"

	"github.com/gomodule/redigo/redis"
)

// RedisDB redis连接池
type RedisDB struct {
	Pool *redis.Pool
}

// Redis 存放redis连接池的变量
var Redis *RedisDB

const (
	// JobPoolKey jobpool
	JobPoolKey = "mq:jobpool"
	// BucketKey bucket
	BucketKey = "mq:bucket"
	// ReadyQueueKey readyqueue
	ReadyQueueKey = "mq:readyqueue"
	// ReadyQueueCacheKey rqcachekey
	ReadyQueueCacheKey = "mq:readyqueuecachekey"
)

func init() {
	Redis = &RedisDB{}
}

// InitPool 新建连接池
func (db *RedisDB) InitPool(host, port, password string, maxIDle, maxActive int) {
	db.Pool = &redis.Pool{
		MaxIdle:     maxIDle,           // 最大空闲链接
		MaxActive:   maxActive,         // 最大链接
		IdleTimeout: 240 * time.Second, // 空闲链接超时
		Wait:        true,              // 当连接池耗尽时,是否阻塞等待
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", host+":"+port, redis.DialPassword(password)) // password 没有密码时password使用空字符串
			if err != nil {
				return nil, err
			}
			return c, nil
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			if time.Since(t) < time.Minute {
				return nil
			}
			_, err := c.Do("PING")
			return err
		},
	}

	// 检查redis是否连接有误
	if _, err := db.Pool.Dial(); err != nil {
		panic(err)
	}
}

// Do 执行redis操作
func (db *RedisDB) Do(command string, args ...interface{}) (interface{}, error) {
	conn := db.Pool.Get()
	defer conn.Close()
	return conn.Do(command, args...)
}

// String  执行redis操作
func (db *RedisDB) String(command string, args ...interface{}) (string, error) {
	return redis.String(db.Do(command, args...))
}

// Bool  执行redis操作
func (db *RedisDB) Bool(command string, args ...interface{}) (bool, error) {
	return redis.Bool(db.Do(command, args...))
}

// Strings  执行redis操作
func (db *RedisDB) Strings(command string, args ...interface{}) ([]string, error) {
	return redis.Strings(db.Do(command, args...))
}

// Int  执行redis操作
func (db *RedisDB) Int(command string, args ...interface{}) (int, error) {
	return redis.Int(db.Do(command, args...))
}

// Ints  执行redis操作
func (db *RedisDB) Ints(command string, args ...interface{}) ([]int, error) {
	return redis.Ints(db.Do(command, args...))
}

// StringMap 执行redis操作
func (db *RedisDB) StringMap(command string, args ...interface{}) (map[string]string, error) {
	return redis.StringMap(db.Do(command, args...))
}

// GetJobKeyByID GetJobKeyByID
func GetJobKeyByID(id string) string {
	return JobPoolKey + ":" + id
}

// GetJobQueueByTopic GetJobQueueByTopic
func GetJobQueueByTopic(topic string) string {
	return ReadyQueueKey + ":" + topic
}

// GetBucketKeyByID GetBucketKeyByID
func GetBucketKeyByID(id string) string {
	return BucketKey + ":" + id
}
